﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Text;

namespace OkTool.Util
{
    /// <summary>
    /// 枚举工具类
    /// </summary>
    public class EnumUtil
    {
        /// <summary>
        /// 将枚举值或者枚举属性名称 转换为Enum对象
        /// </summary>
        /// <param name="value">枚举值</param>
        /// <param name="defaultValue"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T ToEnum<T>(object value, T defaultValue)
        {
           return ConvertUtil.ToEnum<T>(value, defaultValue);
        }

        /// <summary>
        /// 指定类是否为Enum
        /// </summary>
        /// <param name="en"></param>
        /// <returns></returns>
        public static bool IsEnum(object en)
        {
            return en is Enum;
        }

        /// <summary>
        /// 获取枚举值的DescriptionAttribute
        /// </summary>
        /// <param name="en"></param>
        /// <returns></returns>
        public static string GetDescription(Enum en)
        {
            Type type = en.GetType();
            MemberInfo[] memInfo = type.GetMember(en.ToString());
            if (memInfo != null && memInfo.Length > 0)
            {
                object[] attrs = memInfo[0].GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false);
                if (attrs != null && attrs.Length > 0)
                    return ((DescriptionAttribute)attrs[0]).Description;
            }
            return en.ToString();
        }

        /// <summary>
        /// 根据DescriptionAttribute获取枚举类型
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="des"></param>
        /// <returns></returns>
        public static T GetEnum<T>(string des)
        {
            Type type = typeof(T);
            MemberInfo[] memInfo = type.GetMembers();
            foreach (var m in memInfo)
            {
                object[] attrs = m.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false);
                if (attrs != null && attrs.Length > 0 && ((DescriptionAttribute)attrs[0]).Description == des)
                {
                    return (T)Enum.Parse(typeof(T), m.Name);
                }

            }
            return default(T);

        }

        /// <summary>
        /// 将枚举转换为ArrayList
        /// <para>格式 枚举名称:描述</para>
        /// 说明：
        /// 若不是枚举类型，则返回NULL
        /// </summary>
        /// <param name="type">枚举类型</param>
        /// <returns>ArrayList</returns>
        public static ArrayList GetArrayListOfNameAndDesc(Type type)
        {
            try
            {
                if (type.IsEnum)
                {
                    ArrayList _array = new ArrayList();
                    Array _enumValues = Enum.GetValues(type);
                    foreach (Enum value in _enumValues)
                    {
                        _array.Add(new KeyValuePair<Enum, string>(value, GetDescription(value)));
                    }
                    return _array;
                }
                return null;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 将枚举转换为NameValueCollection
        /// <para>格式 枚举名称:枚举值</para>
        /// </summary>
        /// <param name="enumType"></param>
        /// <returns></returns>
        public static NameValueCollection GetListOfNameAndValue(Type enumType)
        {
            try
            {
                NameValueCollection nvc = new NameValueCollection();
                Type typeDescription = typeof(DescriptionAttribute);
                System.Reflection.FieldInfo[] fields = enumType.GetFields();
                string strText = string.Empty;
                string strValue = string.Empty;
                foreach (FieldInfo field in fields)
                {
                    if (field.FieldType.IsEnum)
                    {
                        strValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null)).ToString();
                        nvc.Add(field.Name,strValue);
                    }
                }
                return nvc;
            }
            catch (Exception)
            {
                throw;
            }
        }

    }
}
